package net.zoneland.greenleaf.common.worktimehelper;

import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import net.zoneland.greenleaf.common.date.DateOperation;
import net.zoneland.greenleaf.system.entity.Sys_holidayconf;


/**
 * 时间管理帮助类
 * 对节假日，工作日，休息时间进行管理，计算两个时间点之间的工作时间差
 * @author liyi
 *
 */
public class TimeManager {
	
	public Logger logger = Logger.getLogger( TimeManager.class );
	
	private final int MINUTES_OF_DAY = 24*60; 
	private HolidayManager holidayManager = null;
	private TimeForDayManager timeForDayManager = null;
	
	public TimeManager( HolidayManager _holidayManager, TimeForDayManager _timeForDayManager ){
		holidayManager = _holidayManager;
		timeForDayManager = _timeForDayManager;
	}
	
	public long workTimeDiffForMinutes(Date dateStart) throws ParseException{
		Date dateEnd = new Date();
		return workTimeDiffForMinutes(dateStart, dateEnd);
	}
	
	/**
	 * 计算两个时间之间的工作时间差，精确到分
	 * @param dateStart
	 * @param dateEnd
	 * @return
	 * @throws ParseException
	 */
	public long workTimeDiffForMinutes(Date dateStart, Date dateEnd) throws ParseException{
		DateOperation dateOperation = new DateOperation();
		long	temp_minutes = 0,//记录两个时间之前的分钟差
		    temp_days = 0,//记录两个时间之前的天数差
		    minutes_left_today = 0, //记录今天还有多少分分钟工作时间
		    work_days = 0,thisLeftMinutes;
		Date tmpDayStart = null;
		
		Date tmpStarttime = null, tmpEndtime = null; //用于比对开始的时间段于结束的时间段的先后
		Calendar calendar_date = Calendar.getInstance();
		Calendar calendar_end = Calendar.getInstance();
		calendar_date.setTime(dateStart);
		calendar_end.setTime(dateEnd);		
		/**
		 * 1、要看一下dateStart是否已经是下班时间或者休息时间，如果是，则需要取最近一个工作时间
		 */
		try {
			tmpStarttime = dateOperation.getDateFromString(dateOperation.getDateFromDate(dateStart, "HH:mm:ss"), "HH:mm:ss");
			tmpEndtime = dateOperation.getDateFromString(dateOperation.getDateFromDate(dateEnd, "HH:mm:ss"), "HH:mm:ss");
			//检查当前时间，如果是上班时间之前，要调 为今天上班时间
			tmpDayStart = dateOperation.getDateFromString(dateOperation.getDateFromDate(dateStart, "yyyy-MM-dd") + " "+timeForDayManager.getStartWorkTime(), "yyyy-MM-dd HH:mm:ss");
			if(dateStart.before(tmpDayStart)){//检查当前时间，如果是上班时间之前，要调 为今天上班时间			
				dateStart = tmpDayStart;
			}
			
			//检查当前时间，如果是下班之后，要调整为下一个工作日上班时间			
			//检查当前时间，如果是在节假日，要调整为最一个工作日上班时间
			tmpDayStart = dateOperation.getDateFromString(dateOperation.getDateFromDate(dateStart, "yyyy-MM-dd") + " "+timeForDayManager.getEndWorkTime(), "yyyy-MM-dd HH:mm:ss");
			if(dateStart.after(tmpDayStart) || holidayManager.isHoliday(dateStart)){//检查当前时间，如果是上班时间之前，要调 为今天上班时间			
				calendar_date.setTime(dateStart);
				do{
					//调 为第二天的上班时间
					calendar_date.add(Calendar.DATE, 1);
				}while(holidayManager.isHoliday(calendar_date.getTime()));
				//调整为上班时间
				tmpDayStart = dateOperation.getDateFromString(dateOperation.getDateFromDate(calendar_date.getTime(), "yyyy-MM-dd") + " " +timeForDayManager.getStartWorkTime(), "yyyy-MM-dd HH:mm:ss");
				dateStart = tmpDayStart;
			}
			//检查当前时间，如果是在某个休息时间段内，要调整为该休息时段结束时间
			calendar_date.setTime(dateStart);
		} catch (Exception e1) {
			logger.error("系统异常", e1);
		}
		
		//看看是不是开始时间已经超过结束时间了，如果是的，那就直接返回0
		if(dateStart.after(dateEnd)){
			return 0;
		}
		
		temp_minutes = dateOperation.getDeff(DateFormatUtil.FORMAT.format(calendar_date.getTime()), DateFormatUtil.FORMAT.format(dateEnd));
		//看看两个时间是否相差多于一个工作日了
		temp_days = temp_minutes/MINUTES_OF_DAY;
		
		if(temp_days >0){
			/**
			 * 记录一下今天还有多少分钟，后面把时间设置为后一天的上班时间
			 */
			try {
				minutes_left_today = timeForDayManager.getWorkTimeLeftOfDay(dateOperation.getDateFromDate(dateStart, "yyyy-MM-dd HH:mm:ss"));
				tmpDayStart = dateOperation.getDateFromString(dateOperation.getDateFromDate(dateStart, "yyyy-MM-dd") + " " +timeForDayManager.getStartWorkTime(), "yyyy-MM-dd HH:mm:ss");
				calendar_date.setTime(dateStart);
			} catch (Exception e) {
				logger.error("系统异常", e);
			}
            
			calendar_date.add(Calendar.DATE, 1);
			for(int i=0; i<temp_days; i++){
				//看看后一天没有超过结束时间
				if(!calendar_date.getTime().after(dateEnd)){
					//没有超过，看看这一天是否是节假日
					if(!this.holidayManager.isHoliday(calendar_date.getTime())){
						//不是节假日						
						//如果是结束的那一天，那么就不算，因为结束的那一天持续的时间是会加上的
						if(!DateFormatUtil.isTheSameDay(calendar_date, calendar_end)){
							work_days++;
						}
						
					}
				}
				calendar_date.add(Calendar.DATE, 1);
				/**
				 * 设置为一天开始的时间
				 */
				try {
					tmpDayStart = dateOperation.getDateFromString(dateOperation.getDateFromDate(calendar_date.getTime(), "yyyy-MM-dd") + " "+timeForDayManager.getStartWorkTime(), "yyyy-MM-dd HH:mm:ss");
				} catch (Exception e) {
					logger.error("系统异常", e);
				}
				calendar_date.setTime(tmpDayStart);
				
			}
			//看看增加天数后的这一天是否是最后一天，如果不是，则需要先算前一天的最后的工作时间，再算最后一天的工作时间
			long leftTime = 0;
			long leftTime_nextDay = 0;
			if(DateFormatUtil.isTheSameDay(calendar_date, calendar_end)){
				/**
				 * 要看一下当天是不是休息日，如果是休息日就不计算了
				 */
				if(!this.holidayManager.isHoliday(calendar_date.getTime())){
					//如果不是工作日，那么就计算当天用了多长时间
					leftTime = timeForDayManager.getWorkTimeUsedOfDay(DateFormatUtil.FORMAT.format(calendar_end.getTime()));
				}
			}else{
				/**
				 * 要看一下当天是不是休息日，如果是休息日就不计算了
				 */
				if(!this.holidayManager.isHoliday(calendar_date.getTime())){
					//如果不是休息日，那么就加上当天全天的工作时间
					leftTime = timeForDayManager.getMaxWorkTimeAsMinutes(DateFormatUtil.FORMAT.format(calendar_date.getTime()), DateFormatUtil.FORMAT.format(dateEnd));
				}
				//不是同一天，那就必定是到第二天，不然会在work_days上再加上一天。那么就再判断一下第二天
				//先算当天到当天结束有多少工作时间，再算第二天有多少工作时间
				/**
				 * 要看一下第二天是不是休息日，如果是休息日就不计算了
				 */
				calendar_date.add(Calendar.DATE, 1);
				if(DateFormatUtil.isTheSameDay(calendar_date, calendar_end)){
					if(!this.holidayManager.isHoliday(calendar_end.getTime())){
						leftTime_nextDay = timeForDayManager.getWorkTimeUsedOfDay(DateFormatUtil.FORMAT.format(dateEnd));
					}
				}
				
			}			
			/**
			if(tmpStarttime.after(tmpEndtime)){
				if(work_days ==1){
					work_days ++;
				}
			}
			**/
			return timeForDayManager.getMaxWorkTimeAsMinutes() * (work_days) + minutes_left_today + leftTime + leftTime_nextDay;
			
		} else{
			/**
			 * 如果不跨天，只在当天，那么结束时间一定比开始时间晚，就直接计算结束时间所用的工作时间 减去开始时间所用的工作时间即可
			 */
			if(DateFormatUtil.isTheSameDay(calendar_date, calendar_end)){
				//是同一天
				long workUsedTime_start = timeForDayManager.getWorkTimeUsedOfDay(DateFormatUtil.FORMAT.format(calendar_date.getTime()));
				long workUsedTime_end = timeForDayManager.getWorkTimeUsedOfDay(DateFormatUtil.FORMAT.format(calendar_end.getTime()));
				return workUsedTime_end - workUsedTime_start;
			}else{
				//不是同一天
				long workUsedTime_start=0, workUsedTime_end=0;
				try {
					workUsedTime_start = timeForDayManager.getWorkTimeLeftOfDay(dateOperation.getDateFromDate(calendar_date.getTime(), "yyyy-MM-dd HH:mm:ss"));
					workUsedTime_end = timeForDayManager.getWorkTimeUsedOfDay(dateOperation.getDateFromDate(calendar_end.getTime(), "yyyy-MM-dd HH:mm:ss"));
				} catch (Exception e) {
					logger.error("系统异常", e);
				}
				return workUsedTime_end + workUsedTime_start;
			}			
		}
	}
	
	
	/**
	 * 计算当前时间延后N天后的日期，跳过所有节假日
	 * 
	 * 排除所有的节假日
	 * @param date 日期型，需要操作的时间
	 * @param days 整数型，需要延迟的天数
	 * @return 日期型
	 */
	public Date addDaysInWorkTime(Date date, int days){
		Calendar calendar_date = Calendar.getInstance();
		calendar_date.setTime(date);
		for(int i=0; i<days; i++){
			//先将当前的日期加一天，判断第二天是否是节假日
			calendar_date.add(Calendar.DATE, 1);
			if(this.holidayManager.isHoliday(calendar_date.getTime())){
				i = i - 1;
			}
		}
		return calendar_date.getTime();
	}
	
	
	/**
	 * 计算当前时间延后N分钟后的日期
	 * 
	 * 排除所有的节假日和休息时间
	 * @param date 日期型，需要操作的时间
	 * @param days 整数型，需要延迟的天数
	 * @return 日期型
	 */
	public Date addMinsInWorkTime(Date date, int mins){
		DateOperation dateOperation = new DateOperation();
		Calendar calendar_date = Calendar.getInstance();
		Calendar calendar_date_todayworktime = Calendar.getInstance();
		calendar_date.setTime(date);
		List<Sys_holidayconf> timeQuantumOfDay = timeForDayManager.getForRestTimeQuantumOfDay_List();
		//看看当天是不是休息日，如果是，则需要把开始时间调整到最近的一个工作日的工作时间
		try {
			while(this.holidayManager.isHoliday(calendar_date.getTime())){				
				calendar_date.add(Calendar.DATE, 1);
				//调整到上班时间				
				calendar_date.setTime(dateOperation.getDateFromString(dateOperation.getDate(calendar_date.getTime()) + " " + timeForDayManager.getStartWorkTime(), "yyyy-MM-dd HH:mm:ss"));
			}
		} catch (Exception e) {
				logger.error("系统异常", e);
		}
		//如果当前时间早于上班时间，那么就调整到上班时间开始计算
		try {
			calendar_date_todayworktime.setTime(dateOperation.getDateFromString(dateOperation.getDate(calendar_date.getTime()) + " " + timeForDayManager.getStartWorkTime(), "yyyy-MM-dd HH:mm:ss"));
		} catch (Exception e1) {
			logger.error("系统异常", e1);
		}
		if( date.before(calendar_date_todayworktime.getTime())  ){
			try {
				calendar_date.setTime(dateOperation.getDateFromString(dateOperation.getDate(calendar_date.getTime()) + " " + timeForDayManager.getStartWorkTime(), "yyyy-MM-dd HH:mm:ss"));
			} catch (Exception e) {
					logger.error("系统异常", e);
			}
		}
		
		//看看当天还剩下多长时间，如果剩下的时间比增加的时间长，那么还是当天		
		//如果剩下的时间比增加的时间短，那么需要一天一天地计算了
		try {
			long left_minutes_inday = timeForDayManager.getWorkTimeLeftOfDay(dateOperation.getDateFromDate(calendar_date.getTime(), "yyyy-MM-dd HH:mm:ss"));
			long max_minutes_inday = timeForDayManager.getMaxWorkTimeAsMinutes();
			long tmp_totalLeft = 0;
			//costTimeQuantumId记录已经使用过的时间段
			Map<String, Object> costTimeQuantumId = new HashMap<>();
			Date _time = null, _timeQuantumStarttime = null, _timeQuantumEndtime = null;
			long needToAddMinutes = mins, eslapMinutes = 0, leftMinutes = 0;
			//看看当天的剩余时间是否可以满足要求
			if(left_minutes_inday >= mins){
				//calendar_date.add(Calendar.MINUTE, mins);
				//判断中间的休息时间，如果结束时间跨过了休息时间，则再向前推进休息持续的时间	
				//先判断当前时间的情况，保证开始时间调整为正常工作时间
				boolean needToReturnWhile = true;								
				while(needToReturnWhile){
					needToReturnWhile = false;
					for(Sys_holidayconf holidayconf_tmp : timeQuantumOfDay){
						/**
						 * 1、如果时段的结束时间在比较的时间之前，并且该时段没有被使用过（记录过），说明已经跨越了该时段，记录ID，减出该时段
						 * 2、如果开始时间在比较时间之前，结束时间在比较时间之后，那么说明比较时间处于该时段之间，查看一下，是不是需要加上时间记录为0，
						 * 如果不为0，则处理时间，在该时段结束后加上需要加上的时间并且，还需要加上该时段已经持续的时间
						 * 如果为0，那么只需要加上持续的时间					 * 
						 */					
						if(costTimeQuantumId.get(holidayconf_tmp.getId())==null){
							_time = dateOperation.getDateFromString(dateOperation.getTime(calendar_date.getTime()), "HH:mm:ss");	
							_timeQuantumStarttime = dateOperation.getDateFromString(holidayconf_tmp.getStarttime(), "HH:mm:ss");
							_timeQuantumEndtime = dateOperation.getDateFromString(holidayconf_tmp.getEndtime(), "HH:mm:ss");
							if(_time.after(_timeQuantumEndtime)){
								//结束时间在比较的时间之前,说明 是包括这个休息时段的，后续不再计算了
								//eslapMinutes = dateOperation.getDeff(holidayconf_tmp.getStarttime(), holidayconf_tmp.getEndtime());
								//calendar_date.add(Calendar.MINUTE, (int)eslapMinutes);
								costTimeQuantumId.put(holidayconf_tmp.getId(), holidayconf_tmp);
								break;
							}else if(_timeQuantumEndtime.after(_time) && _time.after(_timeQuantumStarttime)){
								//说明 比较时间处于该时段之间
								//计算这段时间已经持续的时间，把当前时间设置为此时段结束时间，然后把持续时间作为需要增加的时间
								eslapMinutes = dateOperation.getDeff(holidayconf_tmp.getStarttime(), dateOperation.getDateFromDate(_time, "HH:mm:ss"));
								//把时间设定为该时段结束时间+时段持续时间							
								calendar_date.setTime(dateOperation.getDateFromString(dateOperation.getDate(calendar_date.getTime()) + " " + dateOperation.getDateFromDate(_timeQuantumEndtime, "HH:mm:ss"), "yyyy-MM-dd HH:mm:ss"));
								//calendar_date.add(Calendar.MINUTE, (int)eslapMinutes);
								costTimeQuantumId.put(holidayconf_tmp.getId(), holidayconf_tmp);
								needToReturnWhile = true;
								break;
							}
						}
					}
				}				
				
				calendar_date.add(Calendar.MINUTE, (int)mins);
				needToReturnWhile = true;								
				while(needToReturnWhile){
					needToReturnWhile = false;
					for(Sys_holidayconf holidayconf_tmp : timeQuantumOfDay){
						/**
						 * 1、如果时段的结束时间在比较的时间之前，并且该时段没有被使用过（记录过），说明已经跨越了该时段，记录ID，减出该时段
						 * 2、如果开始时间在比较时间之前，结束时间在比较时间之后，那么说明比较时间处于该时段之间，查看一下，是不是需要加上时间记录为0，
						 * 如果不为0，则处理时间，在该时段结束后加上需要加上的时间并且，还需要加上该时段已经持续的时间
						 * 如果为0，那么只需要加上持续的时间					 * 
						 */					
						if(costTimeQuantumId.get(holidayconf_tmp.getId())==null){
							_time = dateOperation.getDateFromString(dateOperation.getTime(calendar_date.getTime()), "HH:mm:ss");	
							_timeQuantumStarttime = dateOperation.getDateFromString(holidayconf_tmp.getStarttime(), "HH:mm:ss");
							_timeQuantumEndtime = dateOperation.getDateFromString(holidayconf_tmp.getEndtime(), "HH:mm:ss");
							if(_time.after(_timeQuantumEndtime)){
								//说明结束时间在比较的时间之前
								eslapMinutes = dateOperation.getDeff(holidayconf_tmp.getStarttime(), holidayconf_tmp.getEndtime());
								calendar_date.add(Calendar.MINUTE, (int)eslapMinutes);
								costTimeQuantumId.put(holidayconf_tmp.getId(), holidayconf_tmp);
								needToReturnWhile = true;
								break;
							}else if(_timeQuantumEndtime.after(_time) && _time.after(_timeQuantumStarttime)){
								//说明 比较时间处于该时段之间
								//计算这段时间已经持续的时间，把当前时间设置为此时段结束时间，然后把持续时间作为需要增加的时间
								eslapMinutes = dateOperation.getDeff(holidayconf_tmp.getStarttime(), dateOperation.getDateFromDate(_time, "HH:mm:ss"));
								//把时间设定为该时段结束时间+时段持续时间							
								calendar_date.setTime(dateOperation.getDateFromString(dateOperation.getDate(calendar_date.getTime()) + " " + dateOperation.getDateFromDate(_timeQuantumEndtime, "HH:mm:ss"), "yyyy-MM-dd HH:mm:ss"));
								calendar_date.add(Calendar.MINUTE, (int)eslapMinutes);
								costTimeQuantumId.put(holidayconf_tmp.getId(), holidayconf_tmp);
								needToReturnWhile = true;
								break;
							}
						}
					}
				}
				
				return calendar_date.getTime();
			}else{
				Date tmp_date = null;
				tmp_totalLeft = mins - left_minutes_inday;
				while(tmp_totalLeft > 0){
					//从第二天的早上开始工作时间开始算，初始化第二天的开始时间
					calendar_date.add(Calendar.DATE, 1);
					if(!this.holidayManager.isHoliday(calendar_date.getTime())){
						String starttime = dateOperation.getDate(calendar_date.getTime())  + " " + timeForDayManager.getStartWorkTime();
						tmp_date = dateOperation.getDateFromString(starttime, "yyyy-MM-dd HH:mm:ss");
						calendar_date.setTime(tmp_date);			
						//看看剩余的时间是不是还是超过一天的工作时间
						if( tmp_totalLeft > max_minutes_inday ) {
							tmp_totalLeft = tmp_totalLeft - max_minutes_inday;
							continue;
						}else{
							//仔细计算当天的具体时间，计算休息时间
							//拿到一天内所有的休息时间，遍历休息时间，看看时间会停留在哪个时段	
							costTimeQuantumId = new HashMap();
							calendar_date.add(Calendar.MINUTE, (int)tmp_totalLeft);
							boolean needToReturnWhile = true;								
							while(needToReturnWhile){
								needToReturnWhile = false;
								for(Sys_holidayconf holidayconf_tmp : timeQuantumOfDay){
									/**
									 * 1、如果时段的结束时间在比较的时间之前，并且该时段没有被使用过（记录过），说明已经跨越了该时段，记录ID，减出该时段
									 * 2、如果开始时间在比较时间之前，结束时间在比较时间之后，那么说明比较时间处于该时段之间，查看一下，是不是需要加上时间记录为0，
									 * 如果不为0，则处理时间，在该时段结束后加上需要加上的时间并且，还需要加上该时段已经持续的时间
									 * 如果为0，那么只需要加上持续的时间					 * 
									 */					
									if(costTimeQuantumId.get(holidayconf_tmp.getId())==null){
										_time = dateOperation.getDateFromString(dateOperation.getTime(calendar_date.getTime()), "HH:mm:ss");	
										_timeQuantumStarttime = dateOperation.getDateFromString(holidayconf_tmp.getStarttime(), "HH:mm:ss");
										_timeQuantumEndtime = dateOperation.getDateFromString(holidayconf_tmp.getEndtime(), "HH:mm:ss");
										if(_time.after(_timeQuantumEndtime)){
											//说明结束时间在比较的时间之前
											eslapMinutes = dateOperation.getDeff(holidayconf_tmp.getStarttime(), holidayconf_tmp.getEndtime());
											calendar_date.add(Calendar.MINUTE, (int)eslapMinutes);
											costTimeQuantumId.put(holidayconf_tmp.getId(), holidayconf_tmp);
											needToReturnWhile = true;
											break;
										}else if(_timeQuantumEndtime.after(_time) && _time.after(_timeQuantumStarttime)){
											//说明 比较时间处于该时段之间
											//计算这段时间已经持续的时间，把当前时间设置为此时段结束时间，然后把持续时间作为需要增加的时间
											eslapMinutes = dateOperation.getDeff(holidayconf_tmp.getStarttime(), dateOperation.getDateFromDate(_time, "HH:mm:ss"));
											//把时间设定为该时段结束时间+时段持续时间							
											calendar_date.setTime(dateOperation.getDateFromString(dateOperation.getDate(calendar_date.getTime()) + " " + dateOperation.getDateFromDate(_timeQuantumEndtime, "HH:mm:ss"), "yyyy-MM-dd HH:mm:ss"));
											calendar_date.add(Calendar.MINUTE, (int)eslapMinutes);
											costTimeQuantumId.put(holidayconf_tmp.getId(), holidayconf_tmp);
											needToReturnWhile = true;
											break;
										}
									}
								}
							}
							break;
						}
					}else{
						continue;
					}
				}
			}
		} catch (ParseException e) {
				logger.error("系统异常", e);
		} catch (Exception e) {
				logger.error("系统异常", e);
		}
		return calendar_date.getTime();
	}
	
	/**
	 * 判断当前时间是否是休息时间
	 * @return
	 * @throws Exception
	 */
	public boolean isWorkTime() throws Exception{
		DateOperation dateOperation = new DateOperation();
		Date date = new Date();
		List<Sys_holidayconf> timeQuantumOfDay = null;
		/**
		 * 看看是不是在节假日
		 */
		if(this.holidayManager.isHoliday(date)){
			return false;
		}		
		/**
		 * 看看是不是在上班时间内
		 */
		Date worktimeStart = dateOperation.getDateFromString(dateOperation.getDateFromDate(date, "yyyy-MM-dd") + " "+timeForDayManager.getStartWorkTime(), "yyyy-MM-dd HH:mm:ss");
		Date worktimeEnd = dateOperation.getDateFromString(dateOperation.getDateFromDate(date, "yyyy-MM-dd") + " "+timeForDayManager.getEndWorkTime(), "yyyy-MM-dd HH:mm:ss");
		if(date.after(worktimeStart) && date.before(worktimeEnd)){
			/**
			 * 看看有没有在某个休息时段内
			 */
			timeQuantumOfDay = timeForDayManager.getForRestTimeQuantumOfDay_List();
			Date _time = null;	
			Date _timeQuantumStarttime = null;
			Date _timeQuantumEndtime = null;
			_time = dateOperation.getDateFromString(dateOperation.getTime(date), "HH:mm:ss");	
			for(Sys_holidayconf holidayconf_tmp : timeQuantumOfDay){				
				_timeQuantumStarttime = dateOperation.getDateFromString(holidayconf_tmp.getStarttime(), "HH:mm:ss");
				_timeQuantumEndtime = dateOperation.getDateFromString(holidayconf_tmp.getEndtime(), "HH:mm:ss");
				if(_timeQuantumEndtime.after(_time) && _time.after(_timeQuantumStarttime)){
					//说明 比较时间处于该时段之间					
					return false;
				}
			}
		}else{
			return false;
		}
		return true;
	}
	
	/**
	 * 判断当前时间是否是休息时间
	 * @return
	 * @throws Exception
	 */
	public boolean isWorkTime( Date date ) throws Exception{
		DateOperation dateOperation = new DateOperation();
		List<Sys_holidayconf> timeQuantumOfDay = null;
		/**
		 * 看看是不是在节假日
		 */
		if(this.holidayManager.isHoliday(date)){
			return false;
		}		
		/**
		 * 看看是不是在上班时间内
		 */
		Date worktimeStart = dateOperation.getDateFromString(dateOperation.getDateFromDate(date, "yyyy-MM-dd") + " "+timeForDayManager.getStartWorkTime(), "yyyy-MM-dd HH:mm:ss");
		Date worktimeEnd = dateOperation.getDateFromString(dateOperation.getDateFromDate(date, "yyyy-MM-dd") + " "+timeForDayManager.getEndWorkTime(), "yyyy-MM-dd HH:mm:ss");
		if(date.after(worktimeStart) && date.before(worktimeEnd)){
			/**
			 * 看看有没有在某个休息时段内
			 */
			timeQuantumOfDay = timeForDayManager.getForRestTimeQuantumOfDay_List();
			Date _time = null;	
			Date _timeQuantumStarttime = null;
			Date _timeQuantumEndtime = null;
			_time = dateOperation.getDateFromString(dateOperation.getTime(date), "HH:mm:ss");	
			for(Sys_holidayconf holidayconf_tmp : timeQuantumOfDay){				
				_timeQuantumStarttime = dateOperation.getDateFromString(holidayconf_tmp.getStarttime(), "HH:mm:ss");
				_timeQuantumEndtime = dateOperation.getDateFromString(holidayconf_tmp.getEndtime(), "HH:mm:ss");
				if(_timeQuantumEndtime.after(_time) && _time.after(_timeQuantumStarttime)){
					//说明 比较时间处于该时段之间					
					return false;
				}
			}
		}else{
			return false;
		}
		return true;
	}
	
	/**
	 * 获取指定月倒数第N个工作日
	 * @param 日期
	 * @param num
	 * @return
	 */
	public Date getTheLastWorkDayInThisMonth( String dateStr,  int num ){
		
		DateOperation dateOperation = new DateOperation();
		Calendar calendar = Calendar.getInstance();
		Date date = null;
		
		try {
			date = dateOperation.getDateFromString( dateStr, "yyyy-MM-dd");		
		} catch (Exception e) {
			date = null;
				logger.error("系统异常", e);
		}
		
		//先获取每月最后一天的日期		
		if( date != null ){
			calendar.setTime(date);
			calendar.add(Calendar.MONTH, 1);    //加一个月
	        calendar.set(Calendar.DATE, 1);        //设置为该月第一天
	        calendar.add(Calendar.DATE, -1);    //再减一天即为上个月最后一天
	        
	      //然后倒数到第5个工作日为止
			for( ; num >0 ; ){
				
				if( holidayManager.isHoliday(calendar.getTime()) ){					
					//这一天是假期，不是工作日					
				}else{				
					num--;				
				}
				if( num > 0){
					//再往前一天
					calendar.add(Calendar.DATE, -1);
				}
			}			
			return calendar.getTime();
		}
		
		return null;
	}
	
	/**
	 * 获取指定月份下一个月的第N个工作日
	 * @param 日期
	 * @param num
	 * @return
	 */
	public Date getTheWorkDayInNextMonth( String dateStr,  int num ){
		
		DateOperation dateOperation = new DateOperation();
		Calendar calendar = Calendar.getInstance();
		Date date = null;
		
		try {
			date = dateOperation.getDateFromString( dateStr, "yyyy-MM-dd");		
		} catch (Exception e) {
			date = null;
				logger.error("系统异常", e);
		}
		
		//先获取每月最后一天的日期		
		if( date != null ){
			calendar.setTime(date);
			calendar.add(Calendar.MONTH, 1);    //加一个月
	        calendar.set(Calendar.DATE, 1);        //设置为该月第一天
	        
	      //然后倒数到第5个工作日为止
			for( ; num >0 ; ){
				
				if( holidayManager.isHoliday(calendar.getTime()) ){					
					//这一天是假期，不是工作日					
				}else{				
					num--;				
				}
				if( num > 0){
					//再往前一天
					calendar.add(Calendar.DATE, 1);
				}
			}			
			return calendar.getTime();
		}
		
		return null;
	}
	
	/**
	 * 获取指定月份的第N个工作日
	 * @param 日期
	 * @param num
	 * @return
	 */
	public Date getTheWorkDayInThisMonth( String dateStr,  int num ){
		
		DateOperation dateOperation = new DateOperation();
		Calendar calendar = Calendar.getInstance();
		Date date = null;
		
		try {
			date = dateOperation.getDateFromString( dateStr, "yyyy-MM-dd");		
		} catch (Exception e) {
			date = null;
				logger.error("系统异常", e);
		}
		
		//先获取每月最后一天的日期		
		if( date != null ){
			calendar.setTime(date);
	        calendar.set(Calendar.DATE, 1);        //设置为该月第一天
	        
	      //然后倒数到第5个工作日为止
			for( ; num >0 ; ){
				
				if( holidayManager.isHoliday(calendar.getTime()) ){					
					//这一天是假期，不是工作日					
				}else{				
					num--;				
				}
				if( num > 0){
					//再往前一天
					calendar.add(Calendar.DATE, 1);
				}
			}			
			return calendar.getTime();
		}
		
		return null;
	}
	
	
	public HolidayManager getHolidayManager() {
		return holidayManager;
	}

	public void setHolidayManager(HolidayManager holidayManager) {
		this.holidayManager = holidayManager;
	}

	public TimeForDayManager getTimeForDayManager() {
		return timeForDayManager;
	}

	public void setTimeForDayManager(TimeForDayManager timeForDayManager) {
		this.timeForDayManager = timeForDayManager;
	}
}
